package com.mt.api.modules.service.impl;

import cn.hutool.core.thread.ThreadUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.mt.common.response.WebResponse;
import com.mt.common.response.WebResponseUtils;
import com.mt.common.utils.PloverDateUtil;
import com.mt.api.constants.constant.Constants;
import com.mt.api.constants.enums.*;
import com.mt.api.core.page.PageFactory;
import com.mt.api.modules.domain.*;
import com.mt.api.modules.domain.bo.*;
import com.mt.api.modules.domain.dto.*;
import com.mt.api.modules.domain.vo.*;
import com.mt.api.modules.manager.*;
import com.mt.api.modules.mapper.AppOrderMapper;
import com.mt.api.modules.mapstruct.AppOrderMapStruct;
import com.mt.api.modules.service.AppOrderService;
import com.mt.api.util.AmountUtil;
import com.mt.api.util.JwtUserUtils;
import com.mt.api.util.SequenceBuilder;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author plover
 * @description 服务实现
 * @date 2020-07-06
 **/
@Slf4j
@Service
@RequiredArgsConstructor
public class AppOrderServiceImpl extends ServiceImpl<AppOrderMapper, AppOrder> implements AppOrderService {

    private final AppOrderDetailServiceImpl orderDetailService;
    private final ICustomerManager customerManager;
    private final AppNewsServiceImpl appNewsService;
    private final ISkuManager skuManager;
    private final IStockManager stockManager;
    private final AppOrderMapStruct appOrderMapStruct;
    private final IOrderManager orderManager;
    private final IOrderDetailManager orderDetailManager;
    private final ICargoManager cargoManager;
    private final ICustomerBillManager customerBillManager;
    private final IOutStoreManager outStoreManager;
    private final IOutStoreDetailManager outStoreDetailManager;

    @Deprecated
    @Override
    public WebResponse pageOrder(AppOrderListBo appOrderListBo) {
        Page page = PageFactory.defaultPage(appOrderListBo.getPageSize(), appOrderListBo.getPageNum());
        LambdaQueryWrapper<AppOrder> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(Objects.nonNull(appOrderListBo.getStatus()), AppOrder::getStatus, appOrderListBo.getStatus());
        wrapper.like(StringUtils.isNotEmpty(appOrderListBo.getSearchVal()), AppOrder::getReceiver, appOrderListBo.getSearchVal());
        if (Objects.equals(appOrderListBo.getOrderByDesc(), 1)) {
            wrapper.orderByDesc(AppOrder::getOrderTime);
        } else {
            wrapper.orderByAsc(AppOrder::getOrderTime);
        }
        Page appOrderPage = baseMapper.selectPage(page, wrapper);
        List<AppOrder> appOrders = appOrderPage.getRecords();
        List<AppOrderVo> orderVoList = convertToOrderVo(appOrders);
        appOrderPage.setRecords(orderVoList);
        return WebResponseUtils.successPage(appOrderPage);
    }

    @Override
    public WebResponse getOrderPage(AppOrderListBo appOrderListBo) {
        Page page = orderManager.getOrderPage(appOrderListBo);
        List<AppOrder> records = page.getRecords();
        List<AppOrderSimpleVo> list = records.stream().map(appOrder -> {
            AppOrderSimpleVo vo = appOrderMapStruct.entityToSimpleVo(appOrder);
            vo.setOrderTime(PloverDateUtil.dateToDisplayTime(appOrder.getOrderTime()));
            if (Objects.equals(appOrder.getType(), OrderTypeEnum.SALES.getCode())) {
                vo.setStatusText(OrderStatusEnum.nameOfCode(vo.getStatus()));
            } else {
                vo.setStatusText(OrderBackStatusEnum.nameOfCode(vo.getStatus()));
            }
            vo.setPrintStatusText(vo.getPrintStatus() == 0 ? "未打印" : vo.getPrintStatus() == 1 ? "已打印" : "打印失败");
            vo.setTypeText(OrderTypeEnum.nameOfCode(vo.getType()));
            return vo;
        }).collect(Collectors.toList());
        page.setRecords(list);
        return WebResponseUtils.successPage(page);
    }

    private List<AppOrderVo> convertToOrderVo(List<AppOrder> appOrders) {
        List<AppOrderVo> appOrderVos = Lists.newArrayList();
        List<Integer> orderIds = appOrders.stream().map(AppOrder::getId).collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(orderIds)) {
            List<AppOrderDetail> orderDetails = orderDetailService.list(Wrappers.<AppOrderDetail>lambdaQuery().in(AppOrderDetail::getOrderId, orderIds));
            appOrders.forEach(appOrder -> {
                AppOrderVo appOrderVo = new AppOrderVo();
                BeanUtils.copyProperties(appOrder, appOrderVo);
                appOrderVo.setStatusName(OrderStatusEnum.nameOfCode(appOrder.getStatus()));
                appOrderVo.setOrderTime(PloverDateUtil.dateFormatyMdHms(appOrder.getOrderTime()));
                //设置配货单明细信息
                List<AppOrderVo.OrderDetailVo> orderDetailVoList = Lists.newArrayList();
                List<AppOrderDetail> orderDetailList = orderDetails.stream().filter(appOrderDetail -> appOrderDetail.getOrderId().equals(appOrder.getId())).collect(Collectors.toList());
                orderDetailList.forEach(appOrderDetail -> {
                    AppOrderVo.OrderDetailVo orderDetailVo = new AppOrderVo.OrderDetailVo();
                    orderDetailVo.setCargoNo(appOrderDetail.getCargoNo());
                    orderDetailVo.setColor(appOrderDetail.getColor());
                    orderDetailVo.setSize(appOrderDetail.getSize());
                    orderDetailVo.setQty(appOrderDetail.getQty());
                    orderDetailVoList.add(orderDetailVo);
                });
                appOrderVo.setOrderDetailList(orderDetailVoList);
                appOrderVos.add(appOrderVo);
            });
        }
        return appOrderVos;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public WebResponse addOrder(AppOrderAddBo orderAddBo) {
        JwtUserDto jwtUser = JwtUserUtils.getJwtUser();

        Integer customerId = orderAddBo.getCustomerId();
        AppCustomer customer = customerManager.getById(customerId);
        if (Objects.isNull(customer)) {
            return WebResponseUtils.error("客户不存在，请先选择客户");
        }

        List<AppOrderDetailAddBo> detailAddBoList = orderAddBo.getOrderDetailData();
        if (CollectionUtils.isEmpty(detailAddBoList)) {
            return WebResponseUtils.error("销售单明细不能为空");
        }

        int totalQty = detailAddBoList.stream().flatMap(appOrderDetailAddBo -> appOrderDetailAddBo.getSkuInfoList().stream())
                .filter(simpleSkuInfo -> Objects.nonNull(simpleSkuInfo.getQty()))
                .mapToInt(AppOrderDetailSkuAddBo::getQty).sum();
        int totalAmount = detailAddBoList.stream().flatMap(appOrderDetailAddBo -> appOrderDetailAddBo.getSkuInfoList().stream())
                .filter(simpleSkuInfo -> Objects.nonNull(simpleSkuInfo.getQty()))
                .mapToInt(value -> value.getQty() * AmountUtil.multiplyHundred(value.getPrice())).sum();

        if (totalQty == 0) {
            return WebResponseUtils.error("销售单数量不能为空");
        }

        SequenceBuilder builder = new SequenceBuilder();
        //配货单主表
        AppOrder appOrder = new AppOrder();
        appOrder.setOrderNo(builder.builderOrderNo());
        appOrder.setOrderTime(new Date());
        appOrder.setRarea(customer.getRarea());
        appOrder.setRaddress(customer.getRaddress());
        appOrder.setReceiver(customer.getReceiver());
        appOrder.setRphone(customer.getRphone());
        appOrder.setStatus(OrderStatusEnum.UN_OUT_STORE.getCode());
        appOrder.setPrintStatus(Constants.OrderPrintState.UN_PRINT);
        appOrder.setType(OrderTypeEnum.SALES.getCode());
        appOrder.setRemark(orderAddBo.getRemark());
        appOrder.setCustomerId(customerId);
        appOrder.setShippingAddress(orderAddBo.getShippingAddress());

        appOrder.setSettleAmount(AmountUtil.multiplyHundred(orderAddBo.getSettleAmount()));
        appOrder.setQty(totalQty);
        appOrder.setAmount(totalAmount);
        if (totalAmount == AmountUtil.multiplyHundred(orderAddBo.getSettleAmount())) {
            appOrder.setSettleStatus(Constants.SettleStatus.SETTLE_FINISH);
        } else {
            appOrder.setSettleStatus(Constants.SettleStatus.UN_SETTLE);
        }
        baseMapper.insert(appOrder);

        StringBuilder thing2Str = new StringBuilder();
        //配货单明细表
        List<AppOrderDetail> orderDetails = Lists.newArrayList();
        for (AppOrderDetailAddBo appOrderDetailAddBo : detailAddBoList) {
            List<AppOrderDetailSkuAddBo> skuInfoList = appOrderDetailAddBo.getSkuInfoList();
            for (AppOrderDetailSkuAddBo detailSkuAddBo : skuInfoList) {
                if (Objects.isNull(detailSkuAddBo.getSkuId()) || Objects.isNull(detailSkuAddBo.getQty()) || detailSkuAddBo.getQty() == 0) {
                    continue;
                }
                Integer skuId = detailSkuAddBo.getSkuId();
                AppSku sku = skuManager.getSkuById(skuId);
                if (Objects.isNull(sku)) {
                    continue;
                }
                AppOrderDetail appOrderDetail = new AppOrderDetail();
                appOrderDetail.setOrderId(appOrder.getId());
                appOrderDetail.setSkuId(sku.getId());
                appOrderDetail.setSkuCode(sku.getSkuCode());
                appOrderDetail.setCargoId(sku.getCargoId());
                appOrderDetail.setCargoNo(sku.getCargoNo());
                appOrderDetail.setColor(sku.getColor());
                appOrderDetail.setSize(sku.getSize());
                appOrderDetail.setQty(detailSkuAddBo.getQty());
                appOrderDetail.setPrice(AmountUtil.multiplyHundred(appOrderDetailAddBo.getWholesalePrice()));
                appOrderDetail.setAmount(detailSkuAddBo.getQty() * AmountUtil.multiplyHundred(appOrderDetailAddBo.getWholesalePrice()));
                orderDetails.add(appOrderDetail);
                thing2Str.append(sku.getCargoNo()).append("-").append(sku.getColor()).append("-")
                        .append(sku.getSize()).append("-").append(detailSkuAddBo.getQty()).append("件").append(";");
            }
        }
        //保存订单明细
        orderDetailService.saveBatch(orderDetails);
        // thing2Str.append("总数量:").append(totalQty.get()).append("件");
        // 处理后置业务  1、收货人处理 2、发送小程序订阅消息 3、添加news
        handlerPostBusiness(appOrder, thing2Str.toString(), totalQty, jwtUser);
        // 客户账单
        editCustomerBill(appOrder.getId(), customerId, appOrder.getAmount(), appOrder.getSettleAmount());
        return WebResponseUtils.success();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public WebResponse editOrder(AppOrderEditBo orderEditBo) {
        AppOrder order = orderManager.getById(orderEditBo.getId());
        if (Objects.isNull(order)) {
            return WebResponseUtils.error("销售单不存在");
        }
        if (order.getStatus() == OrderStatusEnum.CANCEL.getCode()) {
            return WebResponseUtils.error("销售单已撤销，不可修改");
        }

        if (order.getStatus() == OrderStatusEnum.PART_OUT_STORE.getCode() || order.getStatus() == OrderStatusEnum.COMPLETE_OUT_STORE.getCode()) {
            return WebResponseUtils.error("销售单存在已出库的订单，如需修改，请先撤销出库单");
        }
        // 查询库里的订单明细
        List<AppOrderDetail> orderDetailList = orderDetailManager.getOrderDetailByOrderId(orderEditBo.getId());

        List<AppOrderDetailAddBo> orderDetailAddBoList = orderEditBo.getOrderDetailData();

        if (CollectionUtils.isEmpty(orderDetailAddBoList)) {
            return WebResponseUtils.success();
        }

        List<AppOrderDetail> addOrderDetailList = Lists.newArrayList();
        List<AppOrderDetail> updateOrderDetailList = Lists.newArrayList();
        for (AppOrderDetailAddBo orderDetailAddBo : orderDetailAddBoList) {
            for (AppOrderDetailSkuAddBo orderDetailEditBo : orderDetailAddBo.getSkuInfoList()) {
                //按照skuId扣库存
                stockManager.subtractQtyBySkuId(orderDetailEditBo.getSkuId(), orderDetailEditBo.getQty());
                if (Objects.isNull(orderDetailEditBo.getId())) {
                    // 订单明细主键id不存在，则新增
                    AppSku sku = skuManager.getSkuById(orderDetailEditBo.getSkuId());
                    AppOrderDetail orderDetail = new AppOrderDetail();
                    orderDetail.setOrderId(order.getId());
                    orderDetail.setSkuId(sku.getId());
                    orderDetail.setSkuCode(sku.getSkuCode());
                    orderDetail.setCargoId(sku.getCargoId());
                    orderDetail.setCargoNo(sku.getCargoNo());
                    orderDetail.setColor(sku.getColor());
                    orderDetail.setSize(sku.getSize());
                    orderDetail.setQty(orderDetailEditBo.getQty());
                    orderDetail.setPrice(AmountUtil.multiplyHundred(orderDetailEditBo.getPrice()));
                    orderDetail.setAmount(orderDetailEditBo.getQty() * AmountUtil.multiplyHundred(orderDetailEditBo.getPrice()));
                    addOrderDetailList.add(orderDetail);
                } else {
                    AppOrderDetail upOrderDetail = new AppOrderDetail();
                    upOrderDetail.setId(orderDetailEditBo.getId());
                    upOrderDetail.setQty(orderDetailEditBo.getQty());
                    upOrderDetail.setPrice(AmountUtil.multiplyHundred(orderDetailAddBo.getWholesalePrice()));
                    upOrderDetail.setAmount(orderDetailEditBo.getQty() * AmountUtil.multiplyHundred(orderDetailAddBo.getWholesalePrice()));
                    updateOrderDetailList.add(upOrderDetail);
                    //如果订单明细存在，则删除此明细
                    Optional<AppOrderDetail> orderDetailOptional = orderDetailList.stream().filter(appOrderDetail -> Objects.equals(orderDetailEditBo.getId(), appOrderDetail.getId())).findFirst();
                    if (orderDetailOptional.isPresent()) {
                        orderDetailList.remove(orderDetailOptional.get());
                    }
                }
            }
        }

        int addTotalAmount = addOrderDetailList.stream().mapToInt(AppOrderDetail::getAmount).sum();
        int addTotalQty = addOrderDetailList.stream().mapToInt(AppOrderDetail::getQty).sum();
        int updateTotalAmount = updateOrderDetailList.stream().mapToInt(AppOrderDetail::getAmount).sum();
        int updateTotalQty = updateOrderDetailList.stream().mapToInt(AppOrderDetail::getQty).sum();
        //配货单主表
        AppOrder upOrder = new AppOrder();
        upOrder.setId(order.getId());
        upOrder.setRemark(orderEditBo.getRemark());
        upOrder.setQty(addTotalQty + updateTotalQty);
        upOrder.setAmount(addTotalAmount + updateTotalAmount);
        upOrder.setSettleAmount(AmountUtil.multiplyHundred(orderEditBo.getSettleAmount()));
        upOrder.setFinishTime(new Date());
        if (upOrder.getAmount() == AmountUtil.multiplyHundred(orderEditBo.getSettleAmount())) {
            upOrder.setSettleStatus(Constants.SettleStatus.SETTLE_FINISH);
        } else {
            upOrder.setSettleStatus(Constants.SettleStatus.UN_SETTLE);
        }
        upOrder.setShippingAddress(orderEditBo.getShippingAddress());
        orderManager.updateById(upOrder);

        if (CollectionUtils.isNotEmpty(addOrderDetailList)) {
            orderDetailManager.saveBatch(addOrderDetailList);
        }
        if (CollectionUtils.isNotEmpty(updateOrderDetailList)) {
            orderDetailManager.updateBatchById(updateOrderDetailList);
        }
        if (CollectionUtils.isNotEmpty(orderDetailList)) {
            List<Integer> removeIds = orderDetailList.stream().map(AppOrderDetail::getId).collect(Collectors.toList());
            orderDetailManager.removeByIds(removeIds);
        }
        // 客户账单
        editCustomerBill(order.getId(), order.getCustomerId(), upOrder.getAmount(), upOrder.getSettleAmount());
        return WebResponseUtils.success();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public WebResponse partOutStore(AppOrderOutStoreBo resources) {
        AppOrder order = baseMapper.selectById(resources.getId());
        if (Objects.isNull(order)) {
            return WebResponseUtils.error("订单不存在");
        }
        if (!order.getStatus().equals(OrderStatusEnum.UN_OUT_STORE.getCode()) && !order.getStatus().equals(OrderStatusEnum.PART_OUT_STORE.getCode())) {
            return WebResponseUtils.error("订单出库完成或者已撤销");
        }

        List<AppOrderDetailAddBo> orderDetailAddBoList = resources.getOrderDetailData();

        int totalOutStoreQty = orderDetailAddBoList.stream().flatMap(detail -> detail.getSkuInfoList().stream())
                .filter(simpleSkuInfo -> Objects.nonNull(simpleSkuInfo.getQty()))
                .map(AppOrderDetailSkuAddBo::getOutStoreQty).mapToInt(Integer::intValue).sum();

        //保存出库单
        SequenceBuilder builder = new SequenceBuilder();
        OutStore outStore = new OutStore();
        outStore.setOrderId(order.getId());
        outStore.setOutStoreNo(builder.builderOutStoreNo());
        outStore.setOutStoreTime(new Date());
        outStore.setQty(totalOutStoreQty);
        outStore.setType(1);
        outStore.setStatus(OutStoreStatusEnum.FINISHED.getCode());
        outStore.setRemark(resources.getRemark());
        outStore.setShippingAddress(StringUtils.isEmpty(resources.getShippingAddress()) ? order.getShippingAddress() : resources.getShippingAddress());
        outStoreManager.save(outStore);

        int totalAmount = 0;

        List<OutStoreDetail> outStoreDetailList = Lists.newArrayList();
        for (AppOrderDetailAddBo appOrderDetailAddBo : orderDetailAddBoList) {
            List<AppOrderDetailSkuAddBo> skuInfoList = appOrderDetailAddBo.getSkuInfoList();
            for (AppOrderDetailSkuAddBo appOrderDetailSkuAddBo : skuInfoList) {
                Integer id = appOrderDetailSkuAddBo.getId();
                if (Objects.isNull(id)) {
                    continue;
                }
                AppOrderDetail orderDetail = orderDetailManager.getById(id);
                if (Objects.isNull(orderDetail)) {
                    continue;
                }
                // 订单明细主键id不存在，则新增
                AppSku sku = skuManager.getSkuById(appOrderDetailSkuAddBo.getSkuId());
                if (Objects.isNull(sku)) {
                    continue;
                }
                //订单明细出库数量更新
                orderDetailManager.plusOutStoreQty(id, appOrderDetailSkuAddBo.getOutStoreQty());
                //扣除库存
                stockManager.subtractQtyBySkuId(appOrderDetailSkuAddBo.getSkuId(), appOrderDetailSkuAddBo.getOutStoreQty());

                OutStoreDetail outStoreDetail = new OutStoreDetail();
                outStoreDetail.setOrderId(order.getId());
                outStoreDetail.setOrderDetailId(id);
                outStoreDetail.setOutStoreId(outStore.getId());
                outStoreDetail.setSkuId(sku.getId());
                outStoreDetail.setSkuCode(sku.getSkuCode());
                outStoreDetail.setCargoId(sku.getCargoId());
                outStoreDetail.setCargoNo(sku.getCargoNo());
                outStoreDetail.setColor(sku.getColor());
                outStoreDetail.setSize(sku.getSize());
                outStoreDetail.setQty(appOrderDetailSkuAddBo.getOutStoreQty());
                outStoreDetail.setAmount(appOrderDetailSkuAddBo.getOutStoreQty() * orderDetail.getPrice());
                outStoreDetailList.add(outStoreDetail);
                totalAmount += appOrderDetailSkuAddBo.getOutStoreQty() * orderDetail.getPrice();
            }
        }
        //保存出库单明细
        outStoreDetailManager.saveBatch(outStoreDetailList);
        //更新出库金额
        OutStore upOutStore = new OutStore();
        upOutStore.setId(outStore.getId());
        upOutStore.setAmount(totalAmount);
        outStoreManager.updateById(upOutStore);

        //订单主表状态更新
        //如果出库数量等于销售单数量，则销售单全部出库
        if (order.getQty() == (order.getOutStoreQty() + totalOutStoreQty)) {
            orderManager.plusOutStoreQty(resources.getId(), totalOutStoreQty, OrderStatusEnum.COMPLETE_OUT_STORE.getCode(), new Date());
        } else {
            orderManager.plusOutStoreQty(resources.getId(), totalOutStoreQty, OrderStatusEnum.PART_OUT_STORE.getCode(), null);
        }

        handlerPostOutStore(outStore, totalOutStoreQty, JwtUserUtils.getJwtUser());
        return WebResponseUtils.success();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public WebResponse completeOutStore(AppOrderFinishBo orderFinishBo) {
        AppOrder order = baseMapper.selectById(orderFinishBo.getId());
        if (Objects.isNull(order)) {
            return WebResponseUtils.error("订单不存在");
        }
        if (!order.getStatus().equals(OrderStatusEnum.UN_OUT_STORE.getCode()) && !order.getStatus().equals(OrderStatusEnum.PART_OUT_STORE.getCode())) {
            return WebResponseUtils.error("订单出库完成或者已撤销");
        }

        List<AppOrderDetail> orderDetailList = orderDetailManager.getOrderDetailByOrderId(order.getId());
        //待出库总数量
        int totalOutStoreQty = orderDetailList.stream().map(appOrderDetail -> appOrderDetail.getQty() - appOrderDetail.getOutStoreQty())
                .mapToInt(Integer::intValue).sum();

        //保存出库单
        SequenceBuilder builder = new SequenceBuilder();
        OutStore outStore = new OutStore();
        outStore.setOrderId(order.getId());
        outStore.setOutStoreNo(builder.builderOutStoreNo());
        outStore.setOutStoreTime(new Date());
        outStore.setQty(totalOutStoreQty);
        outStore.setType(1);
        outStore.setStatus(OutStoreStatusEnum.FINISHED.getCode());
        outStore.setShippingAddress(order.getShippingAddress());
        outStoreManager.save(outStore);

        List<OutStoreDetail> outStoreDetailList = Lists.newArrayList();
        for (AppOrderDetail orderDetail : orderDetailList) {
            // 订单明细主键id不存在，则新增
            AppSku sku = skuManager.getSkuById(orderDetail.getSkuId());
            if (Objects.isNull(sku)) {
                continue;
            }
            int outStoreQty = orderDetail.getQty() - orderDetail.getOutStoreQty();
            //订单明细出库数量更新
            orderDetailManager.plusOutStoreQty(orderDetail.getId(), outStoreQty);
            //扣除库存
            stockManager.subtractQtyBySkuId(orderDetail.getSkuId(), outStoreQty);

            OutStoreDetail outStoreDetail = new OutStoreDetail();
            outStoreDetail.setOrderId(order.getId());
            outStoreDetail.setOrderDetailId(orderDetail.getId());
            outStoreDetail.setOutStoreId(outStore.getId());
            outStoreDetail.setSkuId(sku.getId());
            outStoreDetail.setSkuCode(sku.getSkuCode());
            outStoreDetail.setCargoId(sku.getCargoId());
            outStoreDetail.setCargoNo(sku.getCargoNo());
            outStoreDetail.setColor(sku.getColor());
            outStoreDetail.setSize(sku.getSize());
            outStoreDetail.setQty(outStoreQty);
            outStoreDetailList.add(outStoreDetail);
        }
        //保存出库单明细
        outStoreDetailManager.saveBatch(outStoreDetailList);

        //订单主表状态更新
        AppOrder appOrder = new AppOrder();
        appOrder.setId(orderFinishBo.getId());
        appOrder.setOutStoreQty(order.getQty());
        //如果出库数量等于销售单数量，则销售单全部出库
        appOrder.setStatus(OrderStatusEnum.COMPLETE_OUT_STORE.getCode());
        appOrder.setFinishTime(new Date());
        baseMapper.updateById(appOrder);

        handlerPostOutStore(outStore, totalOutStoreQty, JwtUserUtils.getJwtUser());
        return WebResponseUtils.success();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public WebResponse cancelOrder(AppOrderFinishBo orderFinishBo) {
        AppOrder order = baseMapper.selectById(orderFinishBo.getId());
        if (Objects.isNull(order)) {
            return WebResponseUtils.error("销售单不存在");
        }
        if (order.getStatus() == OrderStatusEnum.CANCEL.getCode()) {
            return WebResponseUtils.error("销售单已撤销，不可重复撤销");
        }

        if (order.getStatus() == OrderStatusEnum.PART_OUT_STORE.getCode() || order.getStatus() == OrderStatusEnum.COMPLETE_OUT_STORE.getCode()) {
            return WebResponseUtils.error("销售单存在已出库的订单，不可撤销，请先撤销出库单");
        }
        AppOrder appOrder = new AppOrder();
        appOrder.setId(orderFinishBo.getId());
        appOrder.setFinishTime(new Date());
        appOrder.setStatus(OrderStatusEnum.CANCEL.getCode());
        baseMapper.updateById(appOrder);

        // List<OutStore> outStoreList = outStoreManager.getListByOrderId(orderFinishBo.getId());
        // for (OutStore outStore : outStoreList) {
        //     OutStore upOutStore = new OutStore();
        //     upOutStore.setId(outStore.getId());
        //     upOutStore.setStatus(OutStoreStatusEnum.CANCEL.getCode());
        //     outStoreManager.updateById(upOutStore);
        // }
        AppCustomerBill customerBill = customerBillManager.getByBusinessIdAndType(order.getId(), CustomerBillTypeEnum.SALES.getCode());
        if (Objects.nonNull(customerBill)) {
            customerBillManager.removeById(customerBill.getId());
        }
        return WebResponseUtils.success();
    }

    @Override
    public WebResponse printOrder(AppOrderPrintBo param) {
        AppOrder order = baseMapper.selectById(param.getId());
        if (Objects.isNull(order)) {
            return WebResponseUtils.error("订单不存在");
        }
        AppOrder upOrder = new AppOrder();
        upOrder.setId(param.getId());
        upOrder.setPrintStatus(param.getStatus());
        orderManager.updateById(upOrder);
        return WebResponseUtils.success();
    }

    @Override
    public WebResponse orderDetail(Integer orderId) {
        AppOrder appOrder = baseMapper.selectById(orderId);
        List<AppOrderDetail> orderDetails = orderDetailService.list(Wrappers.<AppOrderDetail>lambdaQuery().eq(AppOrderDetail::getOrderId, orderId));
        AppOrderDetailVo result = new AppOrderDetailVo();
        result.setOrder(appOrderMapStruct.entityToSimpleVo(appOrder));
        result.setDetails(appOrderMapStruct.entityToSimpleDetailVoList(orderDetails));
        return WebResponseUtils.success(result);
    }

    @Override
    public WebResponse<AppOrderGroupCargoVo> getOrderDetail(Integer orderId) {
        AppOrder order = orderManager.getById(orderId);
        if (Objects.isNull(order)) {
            return WebResponseUtils.error("配货单不存在");
        }
        AppOrderGroupCargoVo vo = new AppOrderGroupCargoVo();
        //客户账单
        List<CustomerBillStatDto> billStatDtoList = customerBillManager.getCustomerBillStat(order.getCustomerId());
        if (CollectionUtils.isNotEmpty(billStatDtoList)) {
            CustomerBillStatDto customerBillStatDto = billStatDtoList.get(0);
            CustomerBillStatVo billStatVo = new CustomerBillStatVo();
            billStatVo.setCustomerId(order.getCustomerId());
            billStatVo.setSalesAmount(AmountUtil.divideHundred(customerBillStatDto.getSalesAmount()));
            billStatVo.setSettleAmount(AmountUtil.divideHundred(customerBillStatDto.getSettleAmount()));
            billStatVo.setUnSettleAmount(AmountUtil.divideHundred(customerBillStatDto.getUnSettleAmount()));
            vo.setCustomerBillStat(billStatVo);
        }

        //销售单信息
        AppOrderSimpleVo orderSimpleVo = appOrderMapStruct.entityToSimpleVo(order);
        if (Objects.equals(order.getType(), OrderTypeEnum.SALES.getCode())) {
            orderSimpleVo.setStatusText(OrderStatusEnum.nameOfCode(orderSimpleVo.getStatus()));
        } else {
            orderSimpleVo.setStatusText(OrderBackStatusEnum.nameOfCode(orderSimpleVo.getStatus()));
        }
        vo.setOrder(orderSimpleVo);

        //销售单详细信息
        List<AppOrderDetail> orderDetailList = orderDetailManager.getOrderDetailByOrderId(orderId);
        List<AppOrderDetailGroupCargoVo> details = Lists.newArrayList();

        List<Integer> cargoIds = orderDetailList.stream().map(AppOrderDetail::getCargoId).distinct().collect(Collectors.toList());
        List<AppCargo> cargoList = cargoManager.listByIds(cargoIds);

        Map<Integer, List<AppOrderDetail>> cargoMap = orderDetailList.stream().collect(Collectors.groupingBy(AppOrderDetail::getCargoId));
        cargoMap.forEach((cargoId, appOrderDetails) -> {
            AppOrderDetailGroupCargoVo detailGroupCargoVo = new AppOrderDetailGroupCargoVo();

            Optional<AppCargo> cargoOptional = cargoList.stream().filter(o -> Objects.equals(o.getId(), cargoId)).findFirst();
            if (cargoOptional.isPresent()) {
                AppCargo appCargo = cargoOptional.get();
                detailGroupCargoVo.setCargoNo(appCargo.getCargoNo());
                detailGroupCargoVo.setCargoName(appCargo.getRemark());
                detailGroupCargoVo.setPicUrl(appCargo.getPicUrl());
            }
            detailGroupCargoVo.setCargoId(cargoId);
            String price = AmountUtil.divideHundred(appOrderDetails.get(0).getPrice());
            detailGroupCargoVo.setWholesalePrice(price);

            List<AppOrderDetailSimpleVo> simpleVos = Lists.newArrayList();
            for (AppOrderDetail appOrderDetail : appOrderDetails) {
                AppOrderDetailSimpleVo simpleDetailVo = appOrderMapStruct.entityToSimpleDetailVo(appOrderDetail);
                int unOutStoreQty = simpleDetailVo.getQty() - simpleDetailVo.getOutStoreQty();
                simpleDetailVo.setUnOutStoreQty(unOutStoreQty);
                simpleDetailVo.setOutStoreQty(unOutStoreQty);
                simpleVos.add(simpleDetailVo);
            }
            detailGroupCargoVo.setSkuInfoList(simpleVos);
            details.add(detailGroupCargoVo);
        });
        List<AppOrderDetailGroupCargoVo> detailList = details.stream().sorted(Comparator.comparing(AppOrderDetailGroupCargoVo::getCargoNo)).collect(Collectors.toList());
        vo.setDetails(detailList);
        return WebResponseUtils.success(vo);
    }

    /**
     * 编辑客户账单
     *
     * @return
     */
    private boolean editCustomerBill(Integer orderId, Integer customerId, Integer salesAmount, Integer settleAmount) {
        AppCustomerBill customerBill = customerBillManager.getByBusinessIdAndType(orderId, CustomerBillTypeEnum.SALES.getCode());
        if (Objects.nonNull(customerBill)) {
            //更新客户账单
            AppCustomerBill upCustomerBill = new AppCustomerBill();
            upCustomerBill.setId(customerBill.getId());
            upCustomerBill.setSalesAmount(salesAmount);
            upCustomerBill.setSettleAmount(settleAmount);
            customerBillManager.updateById(upCustomerBill);
        } else {
            //保存客户账单
            customerBill = new AppCustomerBill();
            customerBill.setCustomerId(customerId);
            customerBill.setBusinessId(orderId);
            customerBill.setType(CustomerBillTypeEnum.SALES.getCode());
            customerBill.setSalesAmount(salesAmount);
            customerBill.setSettleAmount(settleAmount);
            customerBillManager.save(customerBill);
        }
        return true;
    }

    private void handlerPostBusiness(AppOrder appOrder, String messageContent, Integer totalQty, JwtUserDto jwtUser) {
        ThreadUtil.execAsync(() -> {
            AppNews appNews = new AppNews();
            appNews.setBossId(jwtUser.getAppBoss().getId());
            appNews.setContent(String.format(Constants.ORDER_NEWS_TEMPLATE, appOrder.getReceiver(),
                    appOrder.getRarea(), PloverDateUtil.dateToDisplayTime(appOrder.getOrderTime()), totalQty));
            appNewsService.addNews(appNews);
        });
    }

    private void handlerPostOutStore(OutStore outStore, Integer totalQty, JwtUserDto jwtUser) {
        ThreadUtil.execAsync(() -> {
            AppNews appNews = new AppNews();
            appNews.setBossId(jwtUser.getAppBoss().getId());
            appNews.setContent(String.format(Constants.OUT_STORE_NEWS_TEMPLATE, outStore.getCreator(), PloverDateUtil.dateToDisplayTime(outStore.getOutStoreTime()), totalQty));
            appNewsService.addNews(appNews);
        });
    }
}